classdef DijkstraRouter < Router
    %ROUTER Summary of this class goes here
    %   Detailed explanation goes here
    
    methods
        function obj = DijkstraRouter(topology)
            obj = obj@Router();
            if nargin > 0
                obj.topology = topology;
            end
        end
        
        function packets_for_transmission = get_packets_for_transmission(obj, transmitting_node, packets_vec)
            packets_for_transmission(1,length(packets_vec)) = MultiPacket();
            num_of_packets_for_transmission = 0;
            for i=1:length(packets_vec)
                curr_multi_packet = packets_vec(i);
                if curr_multi_packet.packet.should_be_discarded
                    continue;
                end
                num_of_packets_for_transmission = num_of_packets_for_transmission+1;
                new_multi_packet = curr_multi_packet.duplicate_multi_packet();
                packets_for_transmission(num_of_packets_for_transmission) = new_multi_packet;
                packet = new_multi_packet.packet;
                packet.current_node = transmitting_node;
                %use dijkstra to route the packet
                curr_node = packet.current_node;
                min_cost_to_dest_from_current_node = curr_node.distance_vector(packet.dest_node.id);
                for j=1:length(curr_node.neighbours)
                        min_cost_to_dest_from_current_neighbour = curr_node.neighbours(j).distance_vector(packet.dest_node.id);
                        edge_cost = obj.topology.costs_matrix(curr_node.id, curr_node.neighbours(j).id);
                        if floor(min_cost_to_dest_from_current_node) == floor((min_cost_to_dest_from_current_neighbour+edge_cost))
                            packet.next_node = curr_node.neighbours(j);
                            new_multi_packet.channel_index = j;
                        end
                end
                assert(new_multi_packet.channel_index~=0);
            end
            packets_for_transmission = packets_for_transmission(1:num_of_packets_for_transmission);
        end
        
        function route_packets_to_nodes(obj,packets_to_route)
            global_depositor = GlobalPacketDepositor.instance();
            for i=1:length(packets_to_route)
                curr_multi_packet = packets_to_route(i);
                curr_packet = curr_multi_packet.packet;
                global_depositor.deposit_packet_to_node(curr_packet.next_node.id, curr_multi_packet);
            end
        end
    end
    
end

